package org;

import java.util.concurrent.TimeUnit;

import org.monitoringtools.elements.Counter;
import org.monitoringtools.elements.Monitor;
import org.monitoringtools.manager.MonitorManager;
import org.monitoringtools.util.AssertUtil;

public class TMonitoring implements TMonitoringMBean {

    private final MonitorManager manager = new MonitorManager("Core", "DataSource", "Front-End");

    public long getFailureByMonitor(String id) {
        System.out.println("getFailureByMonitor(String id) called");
        return manager.failure(id);
    }

    public long getFailureByMonitor(String id, String timeUnit) {
        return validateAndGetCounter(id, timeUnit).failure();
    }

    public long getSuccessByMonitor(String id) {
        return manager.success(id);
    }

    public long getSuccessByMonitor(String id, String timeUnit) {
        return validateAndGetCounter(id, timeUnit).success();
    }

    public long getTotalByMonitor(String id) {
        return manager.total(id);
    }

    public long getTotalByMonitor(String id, String timeUnit) {
        return validateAndGetCounter(id, timeUnit).total();
    }

    public void reset() {
        System.out.println("reset() called");
        manager.reset();
    }

    private Counter validateAndGetCounter(String id, String timeUnit) {
        final Monitor monitor = validateAndGetMonitorById(id);
        AssertUtil.assertFieldNotNull(timeUnit, monitor.getCounter(timeUnit), "No monitor found. Please Use [" + getTimeUnitValues() + "]");
        return monitor.getCounter(timeUnit);
    }

    private String getTimeUnitValues() {
        final StringBuilder sb = new StringBuilder();

        for (TimeUnit unit : TimeUnit.values())
            sb.append(unit).append(' ');

        return sb.toString();
    }

    private synchronized Monitor validateAndGetMonitorById(String id) {
        AssertUtil.assertFieldNotNull(id, this.manager.getMonitor(id), "No monitor found");
        return this.manager.getMonitor(id);
    }
}
